{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Python入门(中)</h1>\n",
    "\n",
    "1. [简介](#简介)\n",
    "\n",
    "2. [列表](#列表)<br>\n",
    "   [1. 列表的定义](#1.-列表的定义)<br>\n",
    "   [2. 列表的创建](#2.-列表的创建)<br>\n",
    "   [3. 向列表中添加元素](#3.-向列表中添加元素)<br>\n",
    "   [4. 删除列表中的元素](#4.-删除列表中的元素)<br>\n",
    "   [5. 获取列表中的元素](#5.-获取列表中的元素)<br>\n",
    "   [6. 列表的常用操作符](#6.-列表的常用操作符)<br>\n",
    "   [7. 列表的其它方法](#7.-列表的其它方法)<br>    \n",
    " \n",
    "3. [元组](#元组)<br>\n",
    "   [1. 创建和访问一个元组](#1.-创建和访问一个元组)<br>\n",
    "   [2. 更新和删除一个元组](#2.-更新和删除一个元组)<br>\n",
    "   [3. 元组相关的操作符](#3.-元组相关的操作符)<br>\n",
    "   [4. 内置方法](#4.-内置方法)<br>\n",
    "   [5. 解压元组](#5.-解压元组)<br>\n",
    "   \n",
    "4. [字符串](#字符串)<br>\n",
    "   [1. 字符串的定义](#1.-字符串的定义)<br>\n",
    "   [2. 字符串的切片与拼接](#2.-字符串的切片与拼接)<br>\n",
    "   [3. 字符串的常用内置方法](#3.-字符串的常用内置方法)<br>\n",
    "   [4. 字符串格式化](#4.-字符串格式化)<br>\n",
    "   \n",
    "5. [字典](#字典)<br>\n",
    "   [1. 可变类型与不可变类型](#1.-可变类型与不可变类型)<br>\n",
    "   [2. 字典的定义](#2.-字典的定义)<br>\n",
    "   [3. 创建和访问字典](#3.-创建和访问字典)<br>\n",
    "   [4. 字典的内置方法](#4.-字典的内置方法)<br>\n",
    "   \n",
    "6. [集合](#集合)<br>\n",
    "   [1. 集合的创建](#1.-集合的创建)<br>\n",
    "   [2. 访问集合中的值](#2.-访问集合中的值)<br>\n",
    "   [3. 集合的内置方法](#3.-集合的内置方法)<br>\n",
    "   [4. 集合的转换](#4.-集合的转换)<br>\n",
    "   [5. 不可变集合](#5.-不可变集合)<br>\n",
    "   \n",
    "7. [序列](#序列)<br>\n",
    "   [1. 针对序列的内置函数](#1.-针对序列的内置函数)<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 简介\n",
    "Python 是一种通用编程语言，其在科学计算和机器学习领域具有广泛的应用。\n",
    "\n",
    "本笔记基于阿里云天池龙珠计划 - Python 训练营教程，仅供学习使用。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**本实验包括以下内容**：\n",
    "1. 列表\n",
    "    - 列表的定义\n",
    "    - 列表的创建\n",
    "    - 向列表中添加元素\n",
    "    - 删除列表中的元素\n",
    "    - 获取列表中的元素\n",
    "    - 列表的常用操作符\n",
    "    - 列表的其他方法\n",
    "2. 元组\n",
    "    - 创建和访问一个元组\n",
    "    - 更新和删除一个元组\n",
    "    - 元组相关的操作符\n",
    "    - 内置方法\n",
    "    - 解压元组\n",
    "3. 字符串\n",
    "    - 字符串的定义\n",
    "    - 字符串的切片与拼接\n",
    "    - 字符串的常用内置方法\n",
    "    - 字符串格式化\n",
    "4. 字典\n",
    "    - 可变类型与不可变类型\n",
    "    - 字典的定义\n",
    "    - 创建和访问字典\n",
    "    - 字典的内置方法\n",
    "5. 集合\n",
    "    - 集合的创建\n",
    "    - 访问集合中的值\n",
    "    - 集合的内置方法\n",
    "    - 集合的转换\n",
    "    - 不可变集合\n",
    "6. 序列\n",
    "    - 针对序列的内置函数\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 列表\n",
    "\n",
    "简单数据类型\n",
    "- 整型`<class 'int'>`\n",
    "- 浮点型`<class 'float'>`\n",
    "- 布尔型`<class 'bool'>`\n",
    "\n",
    "容器数据类型\n",
    "- 列表`<class 'list'>`\n",
    "- 元组`<class 'tuple'>`\n",
    "- 字典`<class 'dict'>`\n",
    "- 集合`<class 'set'>`\n",
    "- 字符串`<class 'str'>`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 列表的定义\n",
    "\n",
    "列表是有序集合，没有固定大小，能够保存任意数量任意类型的 Python 对象，语法为 `[元素1, 元素2, ..., 元素n]`。\n",
    "\n",
    "- 关键点是「中括号 []」和「逗号 ,」\n",
    "- 中括号 把所有元素绑在一起\n",
    "- 逗号 将每个元素一一分开\n",
    "\n",
    "\n",
    "\n",
    "## 2. 列表的创建\n",
    "\n",
    "- 创建一个普通列表\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] <class 'list'>\n",
      "[2, 3, 4, 5, 6, 7] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "print(x, type(x))\n",
    "# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] <class 'list'>\n",
    "\n",
    "x = [2, 3, 4, 5, 6, 7]\n",
    "print(x, type(x))\n",
    "# [2, 3, 4, 5, 6, 7] <class 'list'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 利用`range()`创建列表\n",
    "\n",
    "【例子】 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'list'>\n",
      "[1, 3, 5, 7, 9] <class 'list'>\n",
      "[10, 8, 6, 4, 2] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "x = list(range(10))\n",
    "print(x, type(x))\n",
    "# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'list'>\n",
    "\n",
    "x = list(range(1, 11, 2))\n",
    "print(x, type(x))\n",
    "# [1, 3, 5, 7, 9] <class 'list'>\n",
    "\n",
    "x = list(range(10, 1, -2))\n",
    "print(x, type(x))\n",
    "# [10, 8, 6, 4, 2] <class 'list'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 利用推导式创建列表\n",
    "\n",
    "【例子】 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 0, 0, 0, 0] <class 'list'>\n",
      "[0, 0, 0, 0, 0] <class 'list'>\n",
      "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'list'>\n",
      "[1, 3, 5, 7, 9] <class 'list'>\n",
      "[10, 8, 6, 4, 2] <class 'list'>\n",
      "[1, 4, 9, 16, 25, 36, 49, 64, 81] <class 'list'>\n",
      "[3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "x = [0] * 5\n",
    "print(x, type(x))\n",
    "# [0, 0, 0, 0, 0] <class 'list'>\n",
    "\n",
    "x = [0 for i in range(5)]\n",
    "print(x, type(x))\n",
    "# [0, 0, 0, 0, 0] <class 'list'>\n",
    "\n",
    "x = [i for i in range(10)]\n",
    "print(x, type(x))\n",
    "# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'list'>\n",
    "\n",
    "x = [i for i in range(1, 10, 2)]\n",
    "print(x, type(x))\n",
    "# [1, 3, 5, 7, 9] <class 'list'>\n",
    "\n",
    "x = [i for i in range(10, 1, -2)]\n",
    "print(x, type(x))\n",
    "# [10, 8, 6, 4, 2] <class 'list'>\n",
    "\n",
    "x = [i ** 2 for i in range(1, 10)]\n",
    "print(x, type(x))\n",
    "# [1, 4, 9, 16, 25, 36, 49, 64, 81] <class 'list'>\n",
    "\n",
    "x = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]\n",
    "print(x, type(x))\n",
    "\n",
    "# [3, 9, 15, 21, 27, 33, 39,"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "注意：\n",
    "\n",
    "由于list的元素可以是任何对象，因此列表中所保存的是对象的指针。即使保存一个简单的`[1,2,3]`，也有3个指针和3个整数对象。\n",
    "\n",
    "`x = [a] * 4`操作中，只是创建4个指向list的引用，所以一旦`a`改变，`x`中4个`a`也会随之改变。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>\n",
      "[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>\n",
      "[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>\n",
      "[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "x = [[0] * 3] * 4\n",
    "print(x, type(x))\n",
    "# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>\n",
    "\n",
    "x[0][0] = 1\n",
    "print(x, type(x))\n",
    "# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>\n",
    "\n",
    "a = [0] * 3\n",
    "x = [a] * 4\n",
    "print(x, type(x))\n",
    "# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>\n",
    "\n",
    "x[0][0] = 1\n",
    "print(x, type(x))\n",
    "# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "- 创建一个混合列表\n",
    "\n",
    "【例子】 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 'lsgo', 3.14, [1, 2, 3]] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "mix = [1, 'lsgo', 3.14, [1, 2, 3]]\n",
    "print(mix, type(mix))  \n",
    "# [1, 'lsgo', 3.14, [1, 2, 3]] <class 'list'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- 创建一个空列表\n",
    "\n",
    "【例子】 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[] <class 'list'>\n"
     ]
    }
   ],
   "source": [
    "empty = []\n",
    "print(empty, type(empty))  # [] <class 'list'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "列表不像元组，列表内容可更改 (mutable)，因此附加 (`append`, `extend`)、插入 (`insert`)、删除 (`remove`, `pop`) 这些操作都可以用在它身上。\n",
    "\n",
    "\n",
    "## 3. 向列表中添加元素\n",
    "\n",
    "- `list.append(obj)` 在列表末尾添加新的对象，只接受一个参数，参数可以是任何数据类型，被追加的元素在 list 中保持着原结构类型。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday']\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "x.append('Thursday')\n",
    "print(x)  \n",
    "# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday']\n",
    "\n",
    "print(len(x))  # 6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "此元素如果是一个 list，那么这个 list 将作为一个整体进行追加，注意`append()`和`extend()`的区别。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', ['Thursday', 'Sunday']]\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "x.append(['Thursday', 'Sunday'])\n",
    "print(x)  \n",
    "# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', ['Thursday', 'Sunday']]\n",
    "\n",
    "print(len(x))  # 6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `list.extend(seq)` 在列表末尾一次性追加另一个序列中的多个值（用新列表扩展原来的列表）\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday', 'Sunday']\n",
      "7\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "x.extend(['Thursday', 'Sunday'])\n",
    "print(x)  \n",
    "# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday', 'Sunday']\n",
    "\n",
    "print(len(x))  # 7"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "严格来说 `append` 是追加，把一个东西整体添加在列表后，而 `extend` 是扩展，把一个东西里的所有元素添加在列表后。\n",
    "\n",
    "- `list.insert(index, obj)` 在编号 `index` 位置插入 `obj`。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Sunday', 'Wednesday', 'Thursday', 'Friday']\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "x.insert(2, 'Sunday')\n",
    "print(x)\n",
    "# ['Monday', 'Tuesday', 'Sunday', 'Wednesday', 'Thursday', 'Friday']\n",
    "\n",
    "print(len(x))  # 6"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "## 4. 删除列表中的元素\n",
    "- `list.remove(obj)` 移除列表中某个值的第一个匹配项, 且无返回值。如若列表中没有匹配项，将出现ValueError。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Tuesday', 'Wednesday', 'Thursday', 'Friday']\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "x.remove('Monday')\n",
    "print(x)  # ['Tuesday', 'Wednesday', 'Thursday', 'Friday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "- `list.pop([index=-1])` 移除列表中的一个元素（默认最后一个元素），并且返回该元素的值。对于空列表，将出现IndexError。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Friday\n",
      "Monday\n",
      "Wednesday\n",
      "['Tuesday', 'Thursday']\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "y = x.pop()\n",
    "print(y)  # Friday\n",
    "\n",
    "y = x.pop(0)\n",
    "print(y)  # Monday\n",
    "\n",
    "y = x.pop(-2)\n",
    "print(y)  # Wednesday\n",
    "print(x)  # ['Tuesday', 'Thursday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`remove` 和 `pop` 都可以删除元素，前者是指定具体要删除的元素，后者是指定一个索引。\n",
    "\n",
    "- `del var1[, var2 ……]` 删除单个或多个对象。\n",
    "\n",
    "【例子】\n",
    "\n",
    "如果知道要删除的元素在列表中的位置，可使用`del`语句。\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Wednesday', 'Thursday', 'Friday']\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "del x[0:2]\n",
    "print(x)  # ['Wednesday', 'Thursday', 'Friday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "如果你要从列表中删除一个元素，且不再以任何方式使用它，就使用`del`语句；如果你要在删除元素后还能继续使用它，就使用方法`pop()`。\n",
    "\n",
    "\n",
    "## 5. 获取列表中的元素\n",
    "\n",
    "- 通过元素的索引值，从列表获取单个元素，注意，列表索引值是从0开始的。\n",
    "- 通过将索引指定为-1，可让Python返回最后一个列表元素，索引 -2 返回倒数第二个列表元素，以此类推。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Monday <class 'str'>\n",
      "['Thursday', 'Friday'] <class 'list'>\n",
      "Wednesday <class 'str'>\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', ['Thursday', 'Friday']]\n",
    "print(x[0], type(x[0]))  # Monday <class 'str'>\n",
    "print(x[-1], type(x[-1]))  # ['Thursday', 'Friday'] <class 'list'>\n",
    "print(x[-2], type(x[-2]))  # Wednesday <class 'str'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "切片的通用写法是 `start : stop : step`\n",
    "\n",
    "- 情况 1 - \"start :\" \n",
    "- 以 `step` 为 1 (默认) 从编号 `start` 往列表尾部切片。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Thursday', 'Friday']\n",
      "['Wednesday', 'Thursday', 'Friday']\n"
     ]
    }
   ],
   "source": [
    "x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "print(x[3:])  # ['Thursday', 'Friday']\n",
    "print(x[-3:])  # ['Wednesday', 'Thursday', 'Friday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 情况 2 - \": stop\"\n",
    "- 以 `step` 为 1 (默认) 从列表头部往编号 `stop` 切片。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Wednesday']\n",
      "['Monday', 'Tuesday']\n"
     ]
    }
   ],
   "source": [
    "week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "print(week[:3])  # ['Monday', 'Tuesday', 'Wednesday']\n",
    "print(week[:-3])  # ['Monday', 'Tuesday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 情况 3 - \"start : stop\"\n",
    "- 以 `step` 为 1 (默认) 从编号 `start` 往编号 `stop` 切片。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Tuesday', 'Wednesday']\n",
      "['Wednesday', 'Thursday']\n"
     ]
    }
   ],
   "source": [
    "week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "print(week[1:3])  # ['Tuesday', 'Wednesday']\n",
    "print(week[-3:-1])  # ['Wednesday', 'Thursday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 情况 4 - \"start : stop : step\"\n",
    "- 以具体的 `step` 从编号 `start` 往编号 `stop` 切片。注意最后把 `step` 设为 -1，相当于将列表反向排列。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Tuesday', 'Thursday']\n",
      "['Monday', 'Wednesday']\n",
      "['Tuesday', 'Thursday']\n",
      "['Friday', 'Thursday', 'Wednesday', 'Tuesday', 'Monday']\n"
     ]
    }
   ],
   "source": [
    "week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "print(week[1:4:2])  # ['Tuesday', 'Thursday']\n",
    "print(week[:4:2])  # ['Monday', 'Wednesday']\n",
    "print(week[1::2])  # ['Tuesday', 'Thursday']\n",
    "print(week[::-1])  \n",
    "# ['Friday', 'Thursday', 'Wednesday', 'Tuesday', 'Monday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 情况 5 - \" : \"\n",
    "- 复制列表中的所有元素（浅拷贝）。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n"
     ]
    }
   ],
   "source": [
    "week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']\n",
    "print(week[:])  \n",
    "# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】浅拷贝与深拷贝"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[123, 456, 789, 213]\n",
      "[123, 456, 789, 213]\n",
      "[123, 213, 456, 789]\n",
      "[123, 456, 789, 213]\n",
      "[[123, 456], [789, 213]]\n",
      "[[123, 456], [789, 213]]\n",
      "[[123, 456], [789, 213]]\n",
      "[[111, 456], [789, 213]]\n",
      "[[111, 456], [789, 213]]\n",
      "[[123, 456], [789, 213]]\n"
     ]
    }
   ],
   "source": [
    "list1 = [123, 456, 789, 213]\n",
    "list2 = list1\n",
    "list3 = list1[:]\n",
    "\n",
    "print(list2)  # [123, 456, 789, 213]\n",
    "print(list3)  # [123, 456, 789, 213]\n",
    "list1.sort()\n",
    "print(list2)  # [123, 213, 456, 789] \n",
    "print(list3)  # [123, 456, 789, 213]\n",
    "\n",
    "list1 = [[123, 456], [789, 213]]\n",
    "list2 = list1\n",
    "list3 = list1[:]\n",
    "list4 = [[],[]]\n",
    "list4[0] = list1[0][:]\n",
    "list4[1] = list1[1][:]\n",
    "print(list2)  # [[123, 456], [789, 213]]\n",
    "print(list3)  # [[123, 456], [789, 213]]\n",
    "print(list4)  # [[123, 456], [789, 213]]\n",
    "list1[0][0] = 111\n",
    "print(list2)  # [[111, 456], [789, 213]]\n",
    "print(list3)  # [[111, 456], [789, 213]]\n",
    "print(list4)  # [[123, 456], [789, 213]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 列表的常用操作符\n",
    "\n",
    "- 等号操作符：`==`\n",
    "- 连接操作符 `+`\n",
    "- 重复操作符 `*`\n",
    "- 成员关系操作符 `in`、`not in`\n",
    "\n",
    "「等号 ==」，只有成员、成员位置都相同时才返回True。\n",
    "\n",
    "列表拼接有两种方式，用「加号 +」和「乘号 *」，前者首尾拼接，后者复制拼接。\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "[123, 456, 456, 123]\n",
      "[123, 456, 123, 456, 123, 456]\n",
      "[123, 456, 123, 456, 123, 456]\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "list1 = [123, 456]\n",
    "list2 = [456, 123]\n",
    "list3 = [123, 456]\n",
    "\n",
    "print(list1 == list2)  # False\n",
    "print(list1 == list3)  # True\n",
    "\n",
    "list4 = list1 + list2  # extend()\n",
    "print(list4)  # [123, 456, 456, 123]\n",
    "\n",
    "list5 = list3 * 3\n",
    "print(list5)  # [123, 456, 123, 456, 123, 456]\n",
    "\n",
    "list3 *= 3\n",
    "print(list3)  # [123, 456, 123, 456, 123, 456]\n",
    "\n",
    "print(123 in list3)  # True\n",
    "print(456 not in list3)  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "前面三种方法（`append`, `extend`, `insert`）可对列表增加元素，它们没有返回值，是直接修改了原数据对象。\n",
    "而将两个list相加，需要创建新的 list 对象，从而需要消耗额外的内存，特别是当 list 较大时，尽量不要使用 “+” 来添加list。\n",
    "\n",
    "## 7. 列表的其它方法\n",
    "\n",
    "`list.count(obj)` 统计某个元素在列表中出现的次数\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[123, 456, 123, 456, 123, 456]\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "list1 = [123, 456] * 3\n",
    "print(list1)  # [123, 456, 123, 456, 123, 456]\n",
    "num = list1.count(123)\n",
    "print(num)  # 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "`list.index(x[, start[, end]])` 从列表中找出某个值第一个匹配项的索引位置\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "2\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "list1 = [123, 456] * 5\n",
    "print(list1.index(123))  # 0\n",
    "print(list1.index(123, 1))  # 2\n",
    "print(list1.index(123, 3, 7))  # 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "`list.reverse()` 反向列表中元素\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[123, 456, 789] 140053515306248\n",
      "[789, 456, 123] 140053515306248\n"
     ]
    }
   ],
   "source": [
    "x = [123, 456, 789]\n",
    "print(x, id(x))\n",
    "x.reverse()\n",
    "print(x, id(x))  # [789, 456, 123]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "`list.sort(key=None, reverse=False)` 对原列表进行排序。\n",
    "\n",
    "- `key` -- 主要是用来进行比较的元素，只有一个参数，具体的函数的参数就是取自于可迭代对象中，指定可迭代对象中的一个元素来进行排序。\n",
    "- `reverse` -- 排序规则，`reverse = True` 降序， `reverse = False` 升序（默认）。\n",
    "- 该方法没有返回值，但是会对列表的对象进行排序。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[123, 213, 456, 789]\n",
      "[789, 456, 213, 123]\n",
      "[(4, 1), (2, 2), (1, 3), (3, 4)]\n",
      "[(1, 3), (2, 2), (3, 4), (4, 1)]\n"
     ]
    }
   ],
   "source": [
    "x = [123, 456, 789, 213]\n",
    "x.sort()\n",
    "print(x)\n",
    "# [123, 213, 456, 789]\n",
    "\n",
    "x.sort(reverse=True)\n",
    "print(x)\n",
    "# [789, 456, 213, 123]\n",
    "\n",
    "\n",
    "# 获取列表的第二个元素\n",
    "def takeSecond(elem):\n",
    "    return elem[1]\n",
    "\n",
    "\n",
    "x = [(2, 2), (3, 4), (4, 1), (1, 3)]\n",
    "x.sort(key=takeSecond)\n",
    "print(x)\n",
    "# [(4, 1), (2, 2), (1, 3), (3, 4)]\n",
    "\n",
    "x.sort(key=lambda a: a[0])\n",
    "print(x)\n",
    "# [(1, 3), (2, 2), (3, 4), (4, 1)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "# 元组\n",
    "\n",
    "「元组」定义语法为：`(元素1, 元素2, ..., 元素n)`\n",
    "- 小括号把所有元素绑在一起\n",
    "- 逗号将每个元素一一分开\n",
    "\n",
    "## 1. 创建和访问一个元组\n",
    "\n",
    "- Python 的元组与列表类似，不同之处在于tuple被创建后就不能对其进行修改，类似字符串。\n",
    "- 元组使用小括号，列表使用方括号。\n",
    "- 元组与列表类似，也用整数来对它进行索引 (indexing) 和切片 (slicing)。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 10.31, 'python') <class 'tuple'>\n",
      "(1, 10.31, 'python') <class 'tuple'>\n",
      "2\n",
      "(6, 7, 8)\n",
      "(1, 2, 3, 4, 5)\n",
      "(1, 2, 3, 4, 5, 6, 7, 8)\n"
     ]
    }
   ],
   "source": [
    "t1 = (1, 10.31, 'python')\n",
    "t2 = 1, 10.31, 'python'\n",
    "print(t1, type(t1))\n",
    "# (1, 10.31, 'python') <class 'tuple'>\n",
    "\n",
    "print(t2, type(t2))\n",
    "# (1, 10.31, 'python') <class 'tuple'>\n",
    "\n",
    "tuple1 = (1, 2, 3, 4, 5, 6, 7, 8)\n",
    "print(tuple1[1])  # 2\n",
    "print(tuple1[5:])  # (6, 7, 8)\n",
    "print(tuple1[:5])  # (1, 2, 3, 4, 5)\n",
    "tuple2 = tuple1[:]\n",
    "print(tuple2)  # (1, 2, 3, 4, 5, 6, 7, 8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 创建元组可以用小括号 ()，也可以什么都不用，为了可读性，建议还是用 ()。\n",
    "- 元组中只包含一个元素时，需要在元素后面添加逗号，否则括号会被当作运算符使用。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'int'>\n",
      "<class 'tuple'>\n",
      "<class 'list'>\n",
      "<class 'tuple'>\n",
      "<class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "x = (1)\n",
    "print(type(x))  # <class 'int'>\n",
    "x = 2, 3, 4, 5\n",
    "print(type(x))  # <class 'tuple'>\n",
    "x = []\n",
    "print(type(x))  # <class 'list'>\n",
    "x = ()\n",
    "print(type(x))  # <class 'tuple'>\n",
    "x = (1,)\n",
    "print(type(x))  # <class 'tuple'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "64\n",
      "(8, 8, 8, 8, 8, 8, 8, 8)\n"
     ]
    }
   ],
   "source": [
    "print(8 * (8))  # 64\n",
    "print(8 * (8,))  # (8, 8, 8, 8, 8, 8, 8, 8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】创建二维元组。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((1, 10.31, 'python'), ('data', 11))\n",
      "(1, 10.31, 'python')\n",
      "1 10.31 python\n",
      "(1, 10.31)\n"
     ]
    }
   ],
   "source": [
    "x = (1, 10.31, 'python'), ('data', 11)\n",
    "print(x)\n",
    "# ((1, 10.31, 'python'), ('data', 11))\n",
    "\n",
    "print(x[0])\n",
    "# (1, 10.31, 'python')\n",
    "print(x[0][0], x[0][1], x[0][2])\n",
    "# 1 10.31 python\n",
    "\n",
    "print(x[0][0:2])\n",
    "# (1, 10.31)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "## 2. 更新和删除一个元组\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')\n"
     ]
    }
   ],
   "source": [
    "week = ('Monday', 'Tuesday', 'Thursday', 'Friday')\n",
    "week = week[:2] + ('Wednesday',) + week[2:]\n",
    "print(week)  # ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】元组有不可更改 (immutable) 的性质，因此不能直接给元组的元素赋值，但是只要元组中的元素可更改 (mutable)，那么我们可以直接更改其元素，注意这跟赋值其元素不同。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1, 2, 3, [4, 5, 6])\n",
      "(1, 2, 3, [9, 5, 6])\n"
     ]
    }
   ],
   "source": [
    "t1 = (1, 2, 3, [4, 5, 6])\n",
    "print(t1)  # (1, 2, 3, [4, 5, 6])\n",
    "\n",
    "t1[3][0] = 9\n",
    "print(t1)  # (1, 2, 3, [9, 5, 6])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "## 3. 元组相关的操作符\n",
    "\n",
    "- 等号操作符：`==`\n",
    "- 连接操作符 `+`\n",
    "- 重复操作符 `*`\n",
    "- 成员关系操作符 `in`、`not in`\n",
    "\n",
    "「等号 ==」，只有成员、成员位置都相同时才返回True。\n",
    "\n",
    "元组拼接有两种方式，用「加号 +」和「乘号 *」，前者首尾拼接，后者复制拼接。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n",
      "(123, 456, 456, 123)\n",
      "(123, 456, 123, 456, 123, 456)\n",
      "(123, 456, 123, 456, 123, 456)\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "t1 = (123, 456)\n",
    "t2 = (456, 123)\n",
    "t3 = (123, 456)\n",
    "\n",
    "print(t1 == t2)  # False\n",
    "print(t1 == t3)  # True\n",
    "\n",
    "t4 = t1 + t2\n",
    "print(t4)  # (123, 456, 456, 123)\n",
    "\n",
    "t5 = t3 * 3\n",
    "print(t5)  # (123, 456, 123, 456, 123, 456)\n",
    "\n",
    "t3 *= 3\n",
    "print(t3)  # (123, 456, 123, 456, 123, 456)\n",
    "\n",
    "print(123 in t3)  # True\n",
    "print(456 not in t3)  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 4. 内置方法\n",
    "\n",
    "元组大小和内容都不可更改，因此只有 `count` 和 `index` 两种方法。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "t = (1, 10.31, 'python')\n",
    "print(t.count('python'))  # 1\n",
    "print(t.index(10.31))  # 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- `count('python')` 是记录在元组 `t` 中该元素出现几次，显然是 1 次\n",
    "- `index(10.31)` 是找到该元素在元组 `t` 的索引，显然是 1\n",
    "\n",
    "## 5. 解压元组\n",
    "\n",
    "【例子】解压（unpack）一维元组（有几个元素左边括号定义几个变量）\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 10.31 python\n"
     ]
    }
   ],
   "source": [
    "t = (1, 10.31, 'python')\n",
    "(a, b, c) = t\n",
    "print(a, b, c)\n",
    "# 1 10.31 python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】解压二维元组（按照元组里的元组结构来定义变量）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 10.31 OK python\n"
     ]
    }
   ],
   "source": [
    "t = (1, 10.31, ('OK', 'python'))\n",
    "(a, b, (c, d)) = t\n",
    "print(a, b, c, d)\n",
    "# 1 10.31 OK python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】如果你只想要元组其中几个元素，用通配符「*」，英文叫 wildcard，在计算机语言中代表一个或多个元素。下例就是把多个元素丢给了 `rest` 变量。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 5\n",
      "[3, 4]\n"
     ]
    }
   ],
   "source": [
    "t = 1, 2, 3, 4, 5\n",
    "a, b, *rest, c = t\n",
    "print(a, b, c)  # 1 2 5\n",
    "print(rest)  # [3, 4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】如果你根本不在乎 rest 变量，那么就用通配符「*」加上下划线「_」。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2\n"
     ]
    }
   ],
   "source": [
    "t = 1, 2, 3, 4, 5\n",
    "a, b, *_ = t\n",
    "print(a, b)  # 1 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "# 字符串\n",
    "\n",
    "## 1. 字符串的定义\n",
    "- Python 中字符串被定义为引号之间的字符集合。\n",
    "- Python 支持使用成对的 单引号 或 双引号。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i love Python! <class 'str'>\n",
      "I love Python! <class 'str'>\n",
      "13\n",
      "58\n"
     ]
    }
   ],
   "source": [
    "t1 = 'i love Python!'\n",
    "print(t1, type(t1))\n",
    "# i love Python! <class 'str'>\n",
    "\n",
    "t2 = \"I love Python!\"\n",
    "print(t2, type(t2))\n",
    "# I love Python! <class 'str'>\n",
    "\n",
    "print(5 + 8)  # 13\n",
    "print('5' + '8')  # 58"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- Python 的常用转义字符\n",
    "\n",
    "\n",
    "转义字符 | 描述\n",
    ":---:|---\n",
    "`\\\\` | 反斜杠符号\n",
    "`\\'` | 单引号\n",
    "`\\\"` | 双引号\n",
    "`\\n` | 换行\n",
    "`\\t` | 横向制表符(TAB)\n",
    "`\\r` | 回车\n",
    "\n",
    "\n",
    "【例子】如果字符串中需要出现单引号或双引号，可以使用转义符号`\\`对字符串中的符号进行转义。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "let's go\n",
      "let's go\n",
      "C:\\now\n",
      "C:\\Program Files\\Intel\\Wifi\\Help\n"
     ]
    }
   ],
   "source": [
    "print('let\\'s go')  # let's go\n",
    "print(\"let's go\")  # let's go\n",
    "print('C:\\\\now')  # C:\\now\n",
    "print(\"C:\\\\Program Files\\\\Intel\\\\Wifi\\\\Help\")\n",
    "# C:\\Program Files\\Intel\\Wifi\\Help"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "【例子】原始字符串只需要在字符串前边加一个英文字母 r 即可。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\\Program Files\\Intel\\Wifi\\Help\n"
     ]
    }
   ],
   "source": [
    "print(r'C:\\Program Files\\Intel\\Wifi\\Help')  \n",
    "# C:\\Program Files\\Intel\\Wifi\\Help"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "【例子】三引号允许一个字符串跨多行，字符串中可以包含换行符、制表符以及其他特殊字符。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这是一个多行字符串的实例\n",
      "多行字符串可以使用制表符\n",
      "TAB ( \t )。\n",
      "也可以使用换行符 [ \n",
      " ]。\n",
      "\n",
      "这是一个多行字符串的实例\n",
      "多行字符串可以使用制表符\n",
      "TAB ( \t )。\n",
      "也可以使用换行符 [ \n",
      " ]。\n",
      "\n"
     ]
    }
   ],
   "source": [
    "para_str = \"\"\"这是一个多行字符串的实例\n",
    "多行字符串可以使用制表符\n",
    "TAB ( \\t )。\n",
    "也可以使用换行符 [ \\n ]。\n",
    "\"\"\"\n",
    "print(para_str)\n",
    "# 这是一个多行字符串的实例\n",
    "# 多行字符串可以使用制表符\n",
    "# TAB (    )。\n",
    "# 也可以使用换行符 [\n",
    "#  ]。\n",
    "\n",
    "para_str = '''这是一个多行字符串的实例\n",
    "多行字符串可以使用制表符\n",
    "TAB ( \\t )。\n",
    "也可以使用换行符 [ \\n ]。\n",
    "'''\n",
    "print(para_str)\n",
    "# 这是一个多行字符串的实例\n",
    "# 多行字符串可以使用制表符\n",
    "# TAB ( \t )。\n",
    "# 也可以使用换行符 [ \n",
    "#  ]。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "## 2. 字符串的切片与拼接\n",
    "\n",
    "- 类似于元组具有不可修改性\n",
    "- 从 0 开始 (和 Java 一样)\n",
    "- 切片通常写成 `start:end` 这种形式，包括「`start` 索引」对应的元素，不包括「`end`索引」对应的元素。\n",
    "- 索引值可正可负，正索引从 0 开始，从左往右；负索引从 -1 开始，从右往左。使用负数索引时，会从最后一个元素开始计数。最后一个元素的位置编号是 -1。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I Love\n",
      "e\n",
      "I Love 插入的字符串  LsgoGroup\n",
      "Python\n",
      "th\n",
      "yth\n",
      "t\n",
      "n\n"
     ]
    }
   ],
   "source": [
    "str1 = 'I Love LsgoGroup'\n",
    "print(str1[:6])  # I Love\n",
    "print(str1[5])  # e\n",
    "print(str1[:6] + \" 插入的字符串 \" + str1[6:])  \n",
    "# I Love 插入的字符串  LsgoGroup\n",
    "\n",
    "s = 'Python'\n",
    "print(s)  # Python\n",
    "print(s[2:4])  # th\n",
    "print(s[-5:-2])  # yth\n",
    "print(s[2])  # t\n",
    "print(s[-1])  # n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "## 3. 字符串的常用内置方法\n",
    "\n",
    "\n",
    "\n",
    "- `capitalize()` 将字符串的第一个字符转换为大写。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Xiaoxie\n"
     ]
    }
   ],
   "source": [
    "str2 = 'xiaoxie'\n",
    "print(str2.capitalize())  # Xiaoxie"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `lower()` 转换字符串中所有大写字符为小写。\n",
    "- `upper()` 转换字符串中的小写字母为大写。\n",
    "- `swapcase()` 将字符串中大写转换为小写，小写转换为大写。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "daxiexiaoxie\n",
      "DAXIEXIAOXIE\n",
      "daxieXIAOXIE\n"
     ]
    }
   ],
   "source": [
    "str2 = \"DAXIExiaoxie\"\n",
    "print(str2.lower())  # daxiexiaoxie\n",
    "print(str2.upper())  # DAXIEXIAOXIE\n",
    "print(str2.swapcase())  # daxieXIAOXIE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `count(str, beg= 0,end=len(string))` 返回`str`在 string 里面出现的次数，如果`beg`或者`end`指定则返回指定范围内`str`出现的次数。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n"
     ]
    }
   ],
   "source": [
    "str2 = \"DAXIExiaoxie\"\n",
    "print(str2.count('xi'))  # 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `endswith(suffix, beg=0, end=len(string))` 检查字符串是否以指定子字符串 `suffix` 结束，如果是，返回 True，否则返回 False。如果 `beg` 和 `end` 指定值，则在指定范围内检查。\n",
    "- `startswith(substr, beg=0,end=len(string))` 检查字符串是否以指定子字符串 `substr` 开头，如果是，返回 True，否则返回 False。如果 `beg` 和 `end` 指定值，则在指定范围内检查。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "str2 = \"DAXIExiaoxie\"\n",
    "print(str2.endswith('ie'))  # True\n",
    "print(str2.endswith('xi'))  # False\n",
    "print(str2.startswith('Da'))  # False\n",
    "print(str2.startswith('DA'))  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `find(str, beg=0, end=len(string))` 检测 `str` 是否包含在字符串中，如果指定范围 `beg` 和 `end`，则检查是否包含在指定范围内，如果包含，返回开始的索引值，否则返回 -1。\n",
    "- `rfind(str, beg=0,end=len(string))` 类似于 `find()` 函数，不过是从右边开始查找。\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "-1\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "str2 = \"DAXIExiaoxie\"\n",
    "print(str2.find('xi'))  # 5\n",
    "print(str2.find('ix'))  # -1\n",
    "print(str2.rfind('xi'))  # 9"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `isnumeric()` 如果字符串中只包含数字字符，则返回 True，否则返回 False。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "str3 = '12345'\n",
    "print(str3.isnumeric())  # True\n",
    "str3 += 'a'\n",
    "print(str3.isnumeric())  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `ljust(width[, fillchar])`返回一个原字符串左对齐，并使用`fillchar`（默认空格）填充至长度`width`的新字符串。\n",
    "- `rjust(width[, fillchar])`返回一个原字符串右对齐，并使用`fillchar`（默认空格）填充至长度`width`的新字符串。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11010000\n",
      "00001101\n"
     ]
    }
   ],
   "source": [
    "str4 = '1101'\n",
    "print(str4.ljust(8, '0'))  # 11010000\n",
    "print(str4.rjust(8, '0'))  # 00001101"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `lstrip([chars])` 截掉字符串左边的空格或指定字符。\n",
    "- `rstrip([chars])` 删除字符串末尾的空格或指定字符。\n",
    "- `strip([chars])` 在字符串上执行`lstrip()`和`rstrip()`。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I Love LsgoGroup \n",
      " Love LsgoGroup \n",
      " I Love LsgoGroup\n",
      "I Love LsgoGroup\n",
      "I Love LsgoGrou\n"
     ]
    }
   ],
   "source": [
    "str5 = ' I Love LsgoGroup '\n",
    "print(str5.lstrip())  # 'I Love LsgoGroup '\n",
    "print(str5.lstrip().strip('I'))  # ' Love LsgoGroup '\n",
    "print(str5.rstrip())  # ' I Love LsgoGroup'\n",
    "print(str5.strip())  # 'I Love LsgoGroup'\n",
    "print(str5.strip().strip('p'))  # 'I Love LsgoGrou'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `partition(sub)` 找到子字符串sub，把字符串分为一个三元组`(pre_sub,sub,fol_sub)`，如果字符串中不包含sub则返回`('原字符串','','')`。\n",
    "- `rpartition(sub)`类似于`partition()`方法，不过是从右边开始查找。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('I L', 'o', 've LsgoGroup')\n",
      "('I Love LsgoGroup', '', '')\n",
      "('I Love LsgoGr', 'o', 'up')\n"
     ]
    }
   ],
   "source": [
    "str5 = ' I Love LsgoGroup '\n",
    "print(str5.strip().partition('o'))  # ('I L', 'o', 've LsgoGroup')\n",
    "print(str5.strip().partition('m'))  # ('I Love LsgoGroup', '', '')\n",
    "print(str5.strip().rpartition('o'))  # ('I Love LsgoGr', 'o', 'up')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `replace(old, new [, max])` 把 将字符串中的`old`替换成`new`，如果`max`指定，则替换不超过`max`次。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "We Love LsgoGroup\n"
     ]
    }
   ],
   "source": [
    "str5 = ' I Love LsgoGroup '\n",
    "print(str5.strip().replace('I', 'We'))  # We Love LsgoGroup"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `split(str=\"\", num)` 不带参数默认是以空格为分隔符切片字符串，如果`num`参数有设置，则仅分隔`num`个子字符串，返回切片后的子字符串拼接的列表。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['I', 'Love', 'LsgoGroup']\n",
      "['I L', 've Lsg', 'Gr', 'up']\n"
     ]
    }
   ],
   "source": [
    "str5 = ' I Love LsgoGroup '\n",
    "print(str5.strip().split())  # ['I', 'Love', 'LsgoGroup']\n",
    "print(str5.strip().split('o'))  # ['I L', 've Lsg', 'Gr', 'up']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['www.baidu.com.cn']\n",
      "['www', 'baidu', 'com', 'cn']\n",
      "['www.baidu.com.cn']\n",
      "['www', 'baidu.com.cn']\n",
      "['www', 'baidu', 'com.cn']\n",
      "baidu\n",
      "www\n",
      "baidu\n",
      "com.cn\n"
     ]
    }
   ],
   "source": [
    "u = \"www.baidu.com.cn\"\n",
    "# 使用默认分隔符\n",
    "print(u.split())  # ['www.baidu.com.cn']\n",
    "\n",
    "# 以\".\"为分隔符\n",
    "print((u.split('.')))  # ['www', 'baidu', 'com', 'cn']\n",
    "\n",
    "# 分割0次\n",
    "print((u.split(\".\", 0)))  # ['www.baidu.com.cn']\n",
    "\n",
    "# 分割一次\n",
    "print((u.split(\".\", 1)))  # ['www', 'baidu.com.cn']\n",
    "\n",
    "# 分割两次\n",
    "print(u.split(\".\", 2))  # ['www', 'baidu', 'com.cn']\n",
    "\n",
    "# 分割两次，并取序列为1的项\n",
    "print((u.split(\".\", 2)[1]))  # baidu\n",
    "\n",
    "# 分割两次，并把分割后的三个部分保存到三个变量\n",
    "u1, u2, u3 = u.split(\".\", 2)\n",
    "print(u1)  # www\n",
    "print(u2)  # baidu\n",
    "print(u3)  # com.cn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】去掉换行符"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "say\n",
      "hello\n",
      "baby\n",
      "['say', 'hello', 'baby']\n"
     ]
    }
   ],
   "source": [
    "c = '''say\n",
    "hello\n",
    "baby'''\n",
    "\n",
    "print(c)\n",
    "# say\n",
    "# hello\n",
    "# baby\n",
    "\n",
    "print(c.split('\\n'))  # ['say', 'hello', 'baby']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "www.baidu.com\n",
      "['www', 'baidu', 'com']\n"
     ]
    }
   ],
   "source": [
    "string = \"hello boy<[www.baidu.com]>byebye\"\n",
    "print(string.split('[')[1].split(']')[0])  # www.baidu.com\n",
    "print(string.split('[')[1].split(']')[0].split('.'))  # ['www', 'baidu', 'com']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `splitlines([keepends])` 按照行('\\r', '\\r\\n', \\n')分隔，返回一个包含各行作为元素的列表，如果参数`keepends`为 False，不包含换行符，如果为 True，则保留换行符。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['I ', ' Love ', ' LsgoGroup']\n",
      "['I \\n', ' Love \\n', ' LsgoGroup']\n"
     ]
    }
   ],
   "source": [
    "str6 = 'I \\n Love \\n LsgoGroup'\n",
    "print(str6.splitlines())  # ['I ', ' Love ', ' LsgoGroup']\n",
    "print(str6.splitlines(True))  # ['I \\n', ' Love \\n', ' LsgoGroup']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `maketrans(intab, outtab)` 创建字符映射的转换表，第一个参数是字符串，表示需要转换的字符，第二个参数也是字符串表示转换的目标。两字符串须等长。可添加第三个参数(字符串)，表示需要删除的字符。\n",
    "- `translate(table, deletechars=\"\")` 根据参数`table`给出的表，转换字符串的字符，要过滤掉的字符放到`deletechars`参数中。Python3.5及之后版本不支持`deletechars`参数。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{97: 49, 101: 50, 105: 51, 111: 52, 117: 53, 119: None, 33: None}\n",
      "th3s 3s str3ng 2x1mpl2....4\n"
     ]
    }
   ],
   "source": [
    "str7 = 'this is string example....wow!!!'\n",
    "intab = 'aeiou'\n",
    "outtab = '12345'\n",
    "trantab = str7.maketrans(intab, outtab, 'w!')\n",
    "print(trantab)  # {97: 49, 111: 52, 117: 53, 101: 50, 105: 51}\n",
    "print(str7.translate(trantab))  # th3s 3s str3ng 2x1mpl2....4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "## 4. 字符串格式化\n",
    "\n",
    "- `format` 格式化函数\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I Love Lsgogroup\n",
      "I Love Lsgogroup\n",
      "I Love Lsgogroup\n",
      "27.66GB\n"
     ]
    }
   ],
   "source": [
    "str8 = \"{0} Love {1}\".format('I', 'Lsgogroup')  # 位置参数\n",
    "print(str8)  # I Love Lsgogroup\n",
    "\n",
    "str8 = \"{a} Love {b}\".format(a='I', b='Lsgogroup')  # 关键字参数\n",
    "print(str8)  # I Love Lsgogroup\n",
    "\n",
    "str8 = \"{0} Love {b}\".format('I', b='Lsgogroup')  # 位置参数要在关键字参数之前\n",
    "print(str8)  # I Love Lsgogroup\n",
    "\n",
    "str8 = '{0:.2f}{1}'.format(27.658, 'GB')  # 保留小数点后两位\n",
    "print(str8)  # 27.66GB"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- Python 字符串格式化符号\n",
    "\n",
    "\n",
    " 符   号 | 描述\n",
    ":---:|:---\n",
    "%c | 格式化字符及其ASCII码\n",
    "%s | 格式化字符串，用str()方法处理对象\n",
    "%r | 格式化字符串，用rper()方法处理对象\n",
    "%d | 格式化整数\n",
    "%o | 格式化无符号八进制数\n",
    "%x | 格式化无符号十六进制数\n",
    "%X | 格式化无符号十六进制数（大写）\n",
    "%f | 格式化浮点数字，可指定小数点后的精度\n",
    "%e | 用科学计数法格式化浮点数\n",
    "%E | 作用同%e，用科学计数法格式化浮点数\n",
    "%g | 根据值的大小决定使用%f或%e\n",
    "%G | 作用同%g，根据值的大小决定使用%f或%E\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\n",
      "a b c\n",
      "4 + 5 = 9\n",
      "我叫 小明 今年 10 岁!\n",
      "12\n",
      "a\n",
      "A\n",
      "27.658000\n",
      "2.765800e+01\n",
      "2.765800E+01\n",
      "27.658\n",
      "I said: I am 22 years old..\n",
      "I said: 'I am 22 years old.'.\n"
     ]
    }
   ],
   "source": [
    "print('%c' % 97)  # a\n",
    "print('%c %c %c' % (97, 98, 99))  # a b c\n",
    "print('%d + %d = %d' % (4, 5, 9))  # 4 + 5 = 9\n",
    "print(\"我叫 %s 今年 %d 岁!\" % ('小明', 10))  # 我叫 小明 今年 10 岁!\n",
    "print('%o' % 10)  # 12\n",
    "print('%x' % 10)  # a\n",
    "print('%X' % 10)  # A\n",
    "print('%f' % 27.658)  # 27.658000\n",
    "print('%e' % 27.658)  # 2.765800e+01\n",
    "print('%E' % 27.658)  # 2.765800E+01\n",
    "print('%g' % 27.658)  # 27.658\n",
    "text = \"I am %d years old.\" % 22\n",
    "print(\"I said: %s.\" % text)  # I said: I am 22 years old..\n",
    "print(\"I said: %r.\" % text)  # I said: 'I am 22 years old.'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "- 格式化操作符辅助指令\n",
    "\n",
    "符号 | 功能\n",
    ":---:|:---\n",
    "`m.n` | m 是显示的最小总宽度,n 是小数点后的位数（如果可用的话）\n",
    "`-` | 用作左对齐\n",
    "`+` | 在正数前面显示加号( + )\n",
    "`#` | 在八进制数前面显示零('0')，在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')\n",
    "`0` | 显示的数字前面填充'0'而不是默认的空格\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 27.7\n",
      "2.77e+01\n",
      "        10\n",
      "10        \n",
      "+10\n",
      "0o12\n",
      "0x6c\n",
      "0000000005\n"
     ]
    }
   ],
   "source": [
    "print('%5.1f' % 27.658)  # ' 27.7'\n",
    "print('%.2e' % 27.658)  # 2.77e+01\n",
    "print('%10d' % 10)  # '        10'\n",
    "print('%-10d' % 10)  # '10        '\n",
    "print('%+d' % 10)  # +10\n",
    "print('%#o' % 10)  # 0o12\n",
    "print('%#x' % 108)  # 0x6c\n",
    "print('%010d' % 5)  # 0000000005"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "# 字典\n",
    "\n",
    "## 1. 可变类型与不可变类型\n",
    "\n",
    "- 序列是以连续的整数为索引，与此不同的是，字典以\"关键字\"为索引，关键字可以是任意不可变类型，通常用字符串或数值。\n",
    "- 字典是 Python 唯一的一个 <u>映射类型</u>，字符串、元组、列表属于<u>序列类型</u>。\n",
    "\n",
    "那么如何快速判断一个数据类型 `X` 是不是可变类型的呢？两种方法：\n",
    "- 麻烦方法：用 `id(X)` 函数，对 X 进行某种操作，比较操作前后的 `id`，如果不一样，则 `X` 不可变，如果一样，则 `X` 可变。\n",
    "- 便捷方法：用 `hash(X)`，只要不报错，证明 `X` 可被哈希，即不可变，反过来不可被哈希，即可变。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "94666187086368\n",
      "94666187086432\n",
      "140531397273864\n",
      "140531397273864\n"
     ]
    }
   ],
   "source": [
    "i = 1\n",
    "print(id(i))  # 140732167000896\n",
    "i = i + 2\n",
    "print(id(i))  # 140732167000960\n",
    "\n",
    "l = [1, 2]\n",
    "print(id(l))  # 4300825160\n",
    "l.append('Python')\n",
    "print(id(l))  # 4300825160"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 整数 `i` 在加 1 之后的 `id` 和之前不一样，因此加完之后的这个 `i` (虽然名字没变)，但不是加之前的那个 `i` 了，因此整数是不可变类型。\n",
    "- 列表 `l` 在附加 `'Python'` 之后的 `id` 和之前一样，因此列表是可变类型。\n",
    "\n",
    "\n",
    "【例子】\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5755700876815012780\n",
      "-678966542049646583\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'list'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-2-b6453204a26b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhash\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Python'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m  \u001b[0;31m# 1704535747474881831\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhash\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'Python'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      6\u001b[0m \u001b[0;31m# TypeError: unhashable type: 'list'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'list'"
     ]
    }
   ],
   "source": [
    "print(hash('Name'))  # 7047218704141848153\n",
    "\n",
    "print(hash((1, 2, 'Python')))  # 1704535747474881831\n",
    "\n",
    "print(hash([1, 2, 'Python']))\n",
    "# TypeError: unhashable type: 'list'\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'set'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-3-006b96e89e76>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhash\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;31m# TypeError: unhashable type: 'set'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mTypeError\u001b[0m: unhashable type: 'set'"
     ]
    }
   ],
   "source": [
    "print(hash({1, 2, 3}))\n",
    "# TypeError: unhashable type: 'set'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 数值、字符和元组 都能被哈希，因此它们是不可变类型。\n",
    "- 列表、集合、字典不能被哈希，因此它是可变类型。\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## 2. 字典的定义\n",
    "\n",
    "字典 是无序的 键:值（`key:value`）对集合，键必须是互不相同的（在同一个字典之内）。\n",
    "\n",
    "- `dict` 内部存放的顺序和 `key` 放入的顺序是没有关系的。\n",
    "- `dict` 查找和插入的速度极快，不会随着 `key` 的增加而增加，但是需要占用大量的内存。\n",
    "\n",
    "\n",
    "字典 定义语法为 `{元素1, 元素2, ..., 元素n}`\n",
    "\n",
    "- 其中每一个元素是一个「键值对」-- 键:值 (`key:value`)\n",
    "- 关键点是「大括号 {}」,「逗号 ,」和「冒号 :」\n",
    "- 大括号 -- 把所有元素绑在一起\n",
    "- 逗号 -- 将每个键值对分开\n",
    "- 冒号 -- 将键和值分开\n",
    "\n",
    "\n",
    "## 3. 创建和访问字典\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "耐克的口号是: Just do it\n",
      "耐克的口号是: Just do it\n"
     ]
    }
   ],
   "source": [
    "brand = ['李宁', '耐克', '阿迪达斯']\n",
    "slogan = ['一切皆有可能', 'Just do it', 'Impossible is nothing']\n",
    "print('耐克的口号是:', slogan[brand.index('耐克')])  \n",
    "# 耐克的口号是: Just do it\n",
    "\n",
    "dic = {'李宁': '一切皆有可能', '耐克': 'Just do it', '阿迪达斯': 'Impossible is nothing'}\n",
    "print('耐克的口号是:', dic['耐克'])  \n",
    "# 耐克的口号是: Just do it"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "\n",
    "\n",
    "【例子】通过字符串或数值作为`key`来创建字典。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1: 'one', 2: 'two', 3: 'three'}\n",
      "one\n"
     ]
    },
    {
     "ename": "KeyError",
     "evalue": "4",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-5-bb8d02bd63a3>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdic1\u001b[0m\u001b[0;34m)\u001b[0m  \u001b[0;31m# {1: 'one', 2: 'two', 3: 'three'}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdic1\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m  \u001b[0;31m# one\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdic1\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m  \u001b[0;31m# KeyError: 4\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m: 4"
     ]
    }
   ],
   "source": [
    "dic1 = {1: 'one', 2: 'two', 3: 'three'}\n",
    "print(dic1)  # {1: 'one', 2: 'two', 3: 'three'}\n",
    "print(dic1[1])  # one\n",
    "print(dic1[4])  # KeyError: 4\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'rice': 35, 'wheat': 101, 'corn': 67}\n",
      "35\n"
     ]
    }
   ],
   "source": [
    "dic2 = {'rice': 35, 'wheat': 101, 'corn': 67}\n",
    "print(dic2)  # {'wheat': 101, 'corn': 67, 'rice': 35}\n",
    "print(dic2['rice'])  # 35"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "注意：如果我们取的键在字典中不存在，会直接报错`KeyError`。\n",
    "\n",
    "【例子】通过元组作为`key`来创建字典，但一般不这样使用。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{(1, 2, 3): 'Tom', 'Age': 12, 3: [3, 5, 7]}\n",
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "dic = {(1, 2, 3): \"Tom\", \"Age\": 12, 3: [3, 5, 7]}\n",
    "print(dic)  # {(1, 2, 3): 'Tom', 'Age': 12, 3: [3, 5, 7]}\n",
    "print(type(dic))  # <class 'dict'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "通过构造函数`dict`来创建字典。\n",
    "\n",
    "- `dict()` 创建一个空的字典。\n",
    "\n",
    "【例子】通过`key`直接把数据放入字典中，但一个`key`只能对应一个`value`，多次对一个`key`放入 `value`，后面的值会把前面的值冲掉。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "{'a': 11, 'b': 2, 'c': 3}\n",
      "{'a': 11, 'b': 2, 'c': 3, 'd': 4}\n"
     ]
    }
   ],
   "source": [
    "dic = dict()\n",
    "dic['a'] = 1\n",
    "dic['b'] = 2\n",
    "dic['c'] = 3\n",
    "\n",
    "print(dic)\n",
    "# {'a': 1, 'b': 2, 'c': 3}\n",
    "\n",
    "dic['a'] = 11\n",
    "print(dic)\n",
    "# {'a': 11, 'b': 2, 'c': 3}\n",
    "\n",
    "dic['d'] = 4\n",
    "print(dic)\n",
    "# {'a': 11, 'b': 2, 'c': 3, 'd': 4}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict(mapping)` new dictionary initialized from a mapping object's (key, value) pairs\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'apple': 4139, 'peach': 4127, 'cherry': 4098}\n",
      "{'apple': 4139, 'peach': 4127, 'cherry': 4098}\n"
     ]
    }
   ],
   "source": [
    "dic1 = dict([('apple', 4139), ('peach', 4127), ('cherry', 4098)])\n",
    "print(dic1)  # {'cherry': 4098, 'apple': 4139, 'peach': 4127}\n",
    "\n",
    "dic2 = dict((('apple', 4139), ('peach', 4127), ('cherry', 4098)))\n",
    "print(dic2)  # {'peach': 4127, 'cherry': 4098, 'apple': 4139}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict(**kwargs)` -> new dictionary initialized with the name=value pairs in the keyword argument list.  For example:  dict(one=1, two=2)\n",
    "\n",
    "【例子】这种情况下，键只能为字符串类型，并且创建的时候字符串不能加引号，加上就会直接报语法错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': 'Tom', 'age': 10}\n",
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "dic = dict(name='Tom', age=10)\n",
    "print(dic)  # {'name': 'Tom', 'age': 10}\n",
    "print(type(dic))  # <class 'dict'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 4. 字典的内置方法\n",
    "\n",
    "- `dict.fromkeys(seq[, value])` 用于创建一个新字典，以序列 `seq` 中元素做字典的键，`value` 为字典所有键对应的初始值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'name': None, 'age': None, 'sex': None}\n",
      "{'name': 10, 'age': 10, 'sex': 10}\n",
      "{'name': ('小马', '8', '男'), 'age': ('小马', '8', '男'), 'sex': ('小马', '8', '男')}\n"
     ]
    }
   ],
   "source": [
    "seq = ('name', 'age', 'sex')\n",
    "dic1 = dict.fromkeys(seq)\n",
    "print(dic1)\n",
    "# {'name': None, 'age': None, 'sex': None}\n",
    "\n",
    "dic2 = dict.fromkeys(seq, 10)\n",
    "print(dic2)\n",
    "# {'name': 10, 'age': 10, 'sex': 10}\n",
    "\n",
    "dic3 = dict.fromkeys(seq, ('小马', '8', '男'))\n",
    "print(dic3)\n",
    "# {'name': ('小马', '8', '男'), 'age': ('小马', '8', '男'), 'sex': ('小马', '8', '男')}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.keys()`返回一个可迭代对象，可以使用 `list()` 来转换为列表，列表为字典中的所有键。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['Name', 'Age'])\n",
      "['Name', 'Age']\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'lsgogroup', 'Age': 7}\n",
    "print(dic.keys())  # dict_keys(['Name', 'Age'])\n",
    "lst = list(dic.keys())  # 转换为列表\n",
    "print(lst)  # ['Name', 'Age']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.values()`返回一个迭代器，可以使用 `list()` 来转换为列表，列表为字典中的所有值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_values(['female', 7, 'Zara'])\n",
      "['female', 7, 'Zara']\n"
     ]
    }
   ],
   "source": [
    "dic = {'Sex': 'female', 'Age': 7, 'Name': 'Zara'}\n",
    "print(dic.values())\n",
    "# dict_values(['female', 7, 'Zara'])\n",
    "\n",
    "print(list(dic.values()))\n",
    "# [7, 'female', 'Zara']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.items()`以列表返回可遍历的 (键, 值) 元组数组。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_items([('Name', 'Lsgogroup'), ('Age', 7)])\n",
      "(('Name', 'Lsgogroup'), ('Age', 7))\n",
      "[('Name', 'Lsgogroup'), ('Age', 7)]\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'Lsgogroup', 'Age': 7}\n",
    "print(dic.items())\n",
    "# dict_items([('Name', 'Lsgogroup'), ('Age', 7)])\n",
    "\n",
    "print(tuple(dic.items()))\n",
    "# (('Name', 'Lsgogroup'), ('Age', 7))\n",
    "\n",
    "print(list(dic.items()))\n",
    "# [('Name', 'Lsgogroup'), ('Age', 7)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.get(key, default=None)` 返回指定键的值，如果值不在字典中返回默认值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Age 值为 : 27\n",
      "Sex 值为 : NA\n",
      "{'Name': 'Lsgogroup', 'Age': 27}\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'Lsgogroup', 'Age': 27}\n",
    "print(\"Age 值为 : %s\" % dic.get('Age'))  # Age 值为 : 27\n",
    "print(\"Sex 值为 : %s\" % dic.get('Sex', \"NA\"))  # Sex 值为 : NA\n",
    "print(dic)  # {'Name': 'Lsgogroup', 'Age': 27}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.setdefault(key, default=None)`和`get()`方法 类似, 如果键不存在于字典中，将会添加键并将值设为默认值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Age 键的值为 : 7\n",
      "Sex 键的值为 : None\n",
      "{'Name': 'Lsgogroup', 'Age': 7, 'Sex': None}\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'Lsgogroup', 'Age': 7}\n",
    "print(\"Age 键的值为 : %s\" % dic.setdefault('Age', None))  # Age 键的值为 : 7\n",
    "print(\"Sex 键的值为 : %s\" % dic.setdefault('Sex', None))  # Sex 键的值为 : None\n",
    "print(dic)  \n",
    "# {'Age': 7, 'Name': 'Lsgogroup', 'Sex': None}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `key in dict` `in` 操作符用于判断键是否存在于字典中，如果键在字典 dict 里返回`true`，否则返回`false`。而`not in`操作符刚好相反，如果键在字典 dict 里返回`false`，否则返回`true`。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "键 Age 存在\n",
      "键 Sex 不存在\n",
      "键 Age 存在\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'Lsgogroup', 'Age': 7}\n",
    "\n",
    "# in 检测键 Age 是否存在\n",
    "if 'Age' in dic:\n",
    "    print(\"键 Age 存在\")\n",
    "else:\n",
    "    print(\"键 Age 不存在\")\n",
    "\n",
    "# 检测键 Sex 是否存在\n",
    "if 'Sex' in dic:\n",
    "    print(\"键 Sex 存在\")\n",
    "else:\n",
    "    print(\"键 Sex 不存在\")\n",
    "\n",
    "# not in 检测键 Age 是否存在\n",
    "if 'Age' not in dic:\n",
    "    print(\"键 Age 不存在\")\n",
    "else:\n",
    "    print(\"键 Age 存在\")\n",
    "\n",
    "# 键 Age 存在\n",
    "# 键 Sex 不存在\n",
    "# 键 Age 存在"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.pop(key[,default])`删除字典给定键 `key` 所对应的值，返回值为被删除的值。`key` 值必须给出。若`key`不存在，则返回 `default` 值。\n",
    "- `del dict[key]` 删除字典给定键 `key` 所对应的值。若`key`不存在，则会报错。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a {2: [1, 2]}\n",
      "nokey {2: [1, 2]}\n",
      "{}\n"
     ]
    }
   ],
   "source": [
    "dic1 = {1: \"a\", 2: [1, 2]}\n",
    "print(dic1.pop(1), dic1)  # a {2: [1, 2]}\n",
    "\n",
    "# 设置默认值，必须添加，否则报错\n",
    "print(dic1.pop(3, \"nokey\"), dic1)  # nokey {2: [1, 2]}\n",
    "\n",
    "del dic1[2]\n",
    "print(dic1)  # {}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.popitem()`随机返回并删除字典中的一对键和值，如果字典已经为空，却调用了此方法，就报出KeyError异常。\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, [1, 2])\n",
      "{1: 'a'}\n"
     ]
    }
   ],
   "source": [
    "dic1 = {1: \"a\", 2: [1, 2]}\n",
    "print(dic1.popitem())  # {2: [1, 2]}\n",
    "print(dic1)  # (1, 'a')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `dict.clear()`用于删除字典内所有元素。\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "字典长度 : 2\n",
      "字典删除后长度 : 0\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'Zara', 'Age': 7}\n",
    "print(\"字典长度 : %d\" % len(dic))  # 字典长度 : 2\n",
    "dic.clear()\n",
    "print(\"字典删除后长度 : %d\" % len(dic))  \n",
    "# 字典删除后长度 : 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.copy()`返回一个字典的浅复制。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Name': 'Lsgogroup', 'Age': 7, 'Class': 'First'}\n"
     ]
    }
   ],
   "source": [
    "dic1 = {'Name': 'Lsgogroup', 'Age': 7, 'Class': 'First'}\n",
    "dic2 = dic1.copy()\n",
    "print(dic2)  \n",
    "# {'Name': 'Lsgogroup', 'Age': 7, 'Class': 'First'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【例子】直接赋值和 copy 的区别\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "140531265447256\n",
      "140531265447256\n",
      "140531397268176\n",
      "{'user': 'root', 'num': [2, 3]}\n",
      "{'user': 'root', 'num': [2, 3]}\n",
      "{'user': 'lsgogroup', 'num': [2, 3]}\n"
     ]
    }
   ],
   "source": [
    "dic1 = {'user': 'lsgogroup', 'num': [1, 2, 3]}\n",
    "\n",
    "# 引用对象\n",
    "dic2 = dic1  \n",
    "# 浅拷贝父对象（一级目录），子对象（二级目录）不拷贝，还是引用\n",
    "dic3 = dic1.copy()  \n",
    "\n",
    "print(id(dic1))  # 148635574728\n",
    "print(id(dic2))  # 148635574728\n",
    "print(id(dic3))  # 148635574344\n",
    "\n",
    "# 修改 data 数据\n",
    "dic1['user'] = 'root'\n",
    "dic1['num'].remove(1)\n",
    "\n",
    "# 输出结果\n",
    "print(dic1)  # {'user': 'root', 'num': [2, 3]}\n",
    "print(dic2)  # {'user': 'root', 'num': [2, 3]}\n",
    "print(dic3)  # {'user': 'runoob', 'num': [2, 3]}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `dict.update(dict2)`把字典参数 `dict2` 的 `key:value`对 更新到字典 `dict` 里。\n",
    "\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Name': 'Lsgogroup', 'Age': 8, 'Sex': 'female'}\n"
     ]
    }
   ],
   "source": [
    "dic = {'Name': 'Lsgogroup', 'Age': 7}\n",
    "dic2 = {'Sex': 'female', 'Age': 8}\n",
    "dic.update(dic2)\n",
    "print(dic)  \n",
    "# {'Name': 'Lsgogroup', 'Age': 8, 'Sex': 'female'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "# 集合\n",
    "\n",
    "Python 中`set`与`dict`类似，也是一组`key`的集合，但不存储`value`。由于`key`不能重复，所以，在`set`中，没有重复的`key`。\n",
    "\n",
    "注意，`key`为不可变类型，即可哈希的值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n",
      "<class 'set'>\n"
     ]
    }
   ],
   "source": [
    "num = {}\n",
    "print(type(num))  # <class 'dict'>\n",
    "num = {1, 2, 3, 4}\n",
    "print(type(num))  # <class 'set'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 1. 集合的创建\n",
    "\n",
    "- 先创建对象再加入元素。\n",
    "- 在创建空集合的时候只能使用`s = set()`，因为`s = {}`创建的是空字典。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'apple', 'banana'}\n"
     ]
    }
   ],
   "source": [
    "basket = set()\n",
    "basket.add('apple')\n",
    "basket.add('banana')\n",
    "print(basket)  # {'apple', 'banana'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 直接把一堆元素用花括号括起来`{元素1, 元素2, ..., 元素n}`。\n",
    "- 重复元素在`set`中会被自动被过滤。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'orange', 'apple', 'pear', 'banana'}\n"
     ]
    }
   ],
   "source": [
    "basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}\n",
    "print(basket)  # {'orange', 'apple', 'pear', 'banana'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 使用`set(value)`工厂函数，把列表或元组转换成集合。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'Taobao', 'Lsgogroup', 'Google'}\n",
      "{'Taobao', 'Lsgogroup', 'Google'}\n"
     ]
    }
   ],
   "source": [
    "a = set('abracadabra')\n",
    "print(a)  \n",
    "# {'b', 'r', 'c', 'a', 'd'}\n",
    "\n",
    "b = set((\"Google\", \"Lsgogroup\", \"Taobao\", \"Taobao\"))\n",
    "print(b)  \n",
    "# {'Taobao', 'Lsgogroup', 'Google'}\n",
    "\n",
    "c = set([\"Google\", \"Lsgogroup\", \"Taobao\", \"Google\"])\n",
    "print(c)  \n",
    "# {'Taobao', 'Lsgogroup', 'Google'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "【例子】去掉列表中重复的元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2, 3, 4, 5]\n",
      "[0, 1, 2, 3, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "lst = [0, 1, 2, 3, 4, 5, 5, 3, 1]\n",
    "\n",
    "temp = []\n",
    "for item in lst:\n",
    "    if item not in temp:\n",
    "        temp.append(item)\n",
    "\n",
    "print(temp)  # [0, 1, 2, 3, 4, 5]\n",
    "\n",
    "a = set(lst)\n",
    "print(list(a))  # [0, 1, 2, 3, 4, 5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "从结果发现集合的两个特点：无序 (unordered) 和唯一 (unique)。\n",
    "\n",
    "由于 `set` 存储的是无序集合，所以我们不可以为集合创建索引或执行切片(slice)操作，也没有键(keys)可用来获取集合中元素的值，但是可以判断一个元素是否在集合中。\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## 2. 访问集合中的值\n",
    "\n",
    "- 可以使用`len()`內建函数得到集合的大小。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "s = set(['Google', 'Baidu', 'Taobao'])\n",
    "print(len(s))  # 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 可以使用`for`把集合中的数据一个个读取出来。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Taobao\n",
      "Google\n",
      "Baidu\n"
     ]
    }
   ],
   "source": [
    "s = set(['Google', 'Baidu', 'Taobao'])\n",
    "for item in s:\n",
    "    print(item)\n",
    "    \n",
    "# Taobao\n",
    "# Google\n",
    "# Baidu"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- 可以通过`in`或`not in`判断一个元素是否在集合中已经存在\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "s = set(['Google', 'Baidu', 'Taobao'])\n",
    "print('Taobao' in s)  # True\n",
    "print('Facebook' not in s)  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## 3. 集合的内置方法\n",
    "\n",
    "- `set.add(elmnt)`用于给集合添加元素，如果添加的元素在集合中已存在，则不执行任何操作。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'cherry', 'orange', 'apple', 'banana'}\n",
      "{'cherry', 'orange', 'apple', 'banana'}\n"
     ]
    }
   ],
   "source": [
    "fruits = {\"apple\", \"banana\", \"cherry\"}\n",
    "fruits.add(\"orange\")\n",
    "print(fruits)  \n",
    "# {'cherry', 'orange', 'apple', 'banana'}\n",
    "\n",
    "fruits.add(\"apple\")\n",
    "print(fruits)  \n",
    "# {'cherry', 'orange', 'apple', 'banana'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `set.update(set)`用于修改当前集合，可以添加新的元素或集合到当前集合中，如果添加的元素在集合中已存在，则该元素只会出现一次，重复的会忽略。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'cherry', 'google', 'banana', 'baidu', 'apple'}\n",
      "{'lsgo', 'dreamtech', 'google', 'baidu', 'apple'}\n"
     ]
    }
   ],
   "source": [
    "x = {\"apple\", \"banana\", \"cherry\"}\n",
    "y = {\"google\", \"baidu\", \"apple\"}\n",
    "x.update(y)\n",
    "print(x)\n",
    "# {'cherry', 'google', 'banana', 'baidu', 'apple'}\n",
    "\n",
    "y.update([\"lsgo\", \"dreamtech\"])\n",
    "print(y)\n",
    "# {'lsgo', 'dreamtech', 'google', 'baidu', 'apple'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `set.remove(item)` 用于移除集合中的指定元素。如果元素不存在，则会发生错误。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'cherry', 'apple'}\n"
     ]
    }
   ],
   "source": [
    "fruits = {\"apple\", \"banana\", \"cherry\"}\n",
    "fruits.remove(\"banana\")\n",
    "print(fruits)  # {'apple', 'cherry'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `set.discard(value)` 用于移除指定的集合元素。`remove()` 方法在移除一个不存在的元素时会发生错误，而 `discard()` 方法不会。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'cherry', 'apple'}\n"
     ]
    }
   ],
   "source": [
    "fruits = {\"apple\", \"banana\", \"cherry\"}\n",
    "fruits.discard(\"banana\")\n",
    "print(fruits)  # {'apple', 'cherry'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `set.pop()` 用于随机移除一个元素。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'apple', 'banana'}\n",
      "cherry\n"
     ]
    }
   ],
   "source": [
    "fruits = {\"apple\", \"banana\", \"cherry\"}\n",
    "x = fruits.pop()\n",
    "print(fruits)  # {'apple', 'banana'}\n",
    "print(x)  # cherry"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于 set 是无序和无重复元素的集合，所以两个或多个 set 可以做数学意义上的集合操作。\n",
    "- `set.intersection(set1, set2)` 返回两个集合的交集。\n",
    "- `set1 & set2` 返回两个集合的交集。\n",
    "- `set.intersection_update(set1, set2)` 交集，在原始的集合上移除不重叠的元素。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'l', 'z', 'c', 'a', 'm'}\n",
      "{'a', 'c'}\n",
      "{'a', 'c'}\n",
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'a', 'c'}\n"
     ]
    }
   ],
   "source": [
    "a = set('abracadabra')\n",
    "b = set('alacazam')\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "print(b)  # {'l', 'z', 'c', 'a', 'm'}\n",
    "\n",
    "c = a.intersection(b)\n",
    "print(c)  # {'a', 'c'}\n",
    "print(a & b)  # {'a', 'c'}\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "\n",
    "a.intersection_update(b)\n",
    "print(a)  # {'a', 'c'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- `set.union(set1, set2)` 返回两个集合的并集。\n",
    "- `set1 | set2` 返回两个集合的并集。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'l', 'z', 'c', 'a', 'm'}\n",
      "{'l', 'b', 'z', 'r', 'c', 'a', 'd', 'm'}\n",
      "{'l', 'b', 'z', 'r', 'c', 'a', 'd', 'm'}\n"
     ]
    }
   ],
   "source": [
    "a = set('abracadabra')\n",
    "b = set('alacazam')\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "print(b)  # {'l', 'z', 'c', 'a', 'm'}\n",
    "\n",
    "print(a | b)  \n",
    "# {'l', 'b', 'z', 'r', 'c', 'a', 'd', 'm'}\n",
    "\n",
    "c = a.union(b)\n",
    "print(c)  \n",
    "# {'l', 'b', 'z', 'r', 'c', 'a', 'd', 'm'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `set.difference(set)` 返回集合的差集。\n",
    "- `set1 - set2` 返回集合的差集。\n",
    "- `set.difference_update(set)` 集合的差集，直接在原来的集合中移除元素，没有返回值。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'l', 'z', 'c', 'a', 'm'}\n",
      "{'b', 'r', 'd'}\n",
      "{'b', 'r', 'd'}\n",
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'b', 'r', 'd'}\n"
     ]
    }
   ],
   "source": [
    "a = set('abracadabra')\n",
    "b = set('alacazam')\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "print(b)  # {'l', 'z', 'c', 'a', 'm'}\n",
    "\n",
    "c = a.difference(b)\n",
    "print(c)  # {'b', 'r', 'd'}\n",
    "print(a - b)  # {'b', 'r', 'd'}\n",
    "\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "a.difference_update(b)\n",
    "print(a)  # {'b', 'r', 'd'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `set.symmetric_difference(set)`返回集合的异或。\n",
    "- `set1 ^ set2` 返回集合的异或。\n",
    "- `set.symmetric_difference_update(set)`移除当前集合中在另外一个指定集合相同的元素，并将另外一个指定集合中不同的元素插入到当前集合中。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'l', 'z', 'c', 'a', 'm'}\n",
      "{'l', 'z', 'b', 'm', 'd', 'r'}\n",
      "{'l', 'z', 'b', 'm', 'd', 'r'}\n",
      "{'b', 'r', 'c', 'a', 'd'}\n",
      "{'l', 'b', 'z', 'r', 'd', 'm'}\n"
     ]
    }
   ],
   "source": [
    "a = set('abracadabra')\n",
    "b = set('alacazam')\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "print(b)  # {'l', 'z', 'c', 'a', 'm'}\n",
    "\n",
    "c = a.symmetric_difference(b)\n",
    "print(c)  # {'l', 'z', 'b', 'm', 'd', 'r'}\n",
    "print(a ^ b)  # {'l', 'z', 'b', 'm', 'd', 'r'}\n",
    "\n",
    "print(a)  # {'b', 'r', 'c', 'a', 'd'}\n",
    "a.symmetric_difference_update(b)\n",
    "print(a)  # {'l', 'b', 'z', 'r', 'd', 'm'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `set.issubset(set)`判断集合是不是被其他集合包含，如果是则返回 True，否则返回 False。\n",
    "- `set1 <= set2` 判断集合是不是被其他集合包含，如果是则返回 True，否则返回 False。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "x = {\"a\", \"b\", \"c\"}\n",
    "y = {\"f\", \"e\", \"d\", \"c\", \"b\", \"a\"}\n",
    "z = x.issubset(y)\n",
    "print(z)  # True\n",
    "print(x <= y)  # True\n",
    "\n",
    "x = {\"a\", \"b\", \"c\"}\n",
    "y = {\"f\", \"e\", \"d\", \"c\", \"b\"}\n",
    "z = x.issubset(y)\n",
    "print(z)  # False\n",
    "print(x <= y)  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `set.issuperset(set)`用于判断集合是不是包含其他集合，如果是则返回 True，否则返回 False。\n",
    "- `set1 >= set2` 判断集合是不是包含其他集合，如果是则返回 True，否则返回 False。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "x = {\"f\", \"e\", \"d\", \"c\", \"b\", \"a\"}\n",
    "y = {\"a\", \"b\", \"c\"}\n",
    "z = x.issuperset(y)\n",
    "print(z)  # True\n",
    "print(x >= y)  # True\n",
    "\n",
    "x = {\"f\", \"e\", \"d\", \"c\", \"b\"}\n",
    "y = {\"a\", \"b\", \"c\"}\n",
    "z = x.issuperset(y)\n",
    "print(z)  # False\n",
    "print(x >= y)  # False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- `set.isdisjoint(set)` 用于判断两个集合是不是不相交，如果是返回 True，否则返回 False。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "x = {\"f\", \"e\", \"d\", \"c\", \"b\"}\n",
    "y = {\"a\", \"b\", \"c\"}\n",
    "z = x.isdisjoint(y)\n",
    "print(z)  # False\n",
    "\n",
    "x = {\"f\", \"e\", \"d\", \"m\", \"g\"}\n",
    "y = {\"a\", \"b\", \"c\"}\n",
    "z = x.isdisjoint(y)\n",
    "print(z)  # True"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 集合的转换\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0, 1, 2, 3} <class 'set'>\n",
      "[0, 1, 2, 3] <class 'list'>\n",
      "(0, 1, 2, 3) <class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "se = set(range(4))\n",
    "li = list(se)\n",
    "tu = tuple(se)\n",
    "\n",
    "print(se, type(se))  # {0, 1, 2, 3} <class 'set'>\n",
    "print(li, type(li))  # [0, 1, 2, 3] <class 'list'>\n",
    "print(tu, type(tu))  # (0, 1, 2, 3) <class 'tuple'>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 不可变集合\n",
    "\n",
    "Python 提供了不能改变元素的集合的实现版本，即不能增加或删除元素，类型名叫`frozenset`。需要注意的是`frozenset`仍然可以进行集合操作，只是不能用带有`update`的方法。\n",
    "\n",
    "- `frozenset([iterable])` 返回一个冻结的集合，冻结后集合不能再添加或删除任何元素。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})\n",
      "frozenset({'l', 's', 'r', 'p', 'o', 'u', 'g'})\n"
     ]
    }
   ],
   "source": [
    "a = frozenset(range(10))  # 生成一个新的不可变集合\n",
    "print(a)  \n",
    "# frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})\n",
    "\n",
    "b = frozenset('lsgogroup')\n",
    "print(b)  \n",
    "# frozenset({'g', 's', 'p', 'r', 'u', 'o', 'l'})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 序列\n",
    "\n",
    "在 Python 中，序列类型包括字符串、列表、元组、集合和字典，这些序列支持一些通用的操作，但比较特殊的是，集合和字典不支持索引、切片、相加和相乘操作。\n",
    "\n",
    "## 1. 针对序列的内置函数\n",
    "\n",
    "- `list(sub)` 把一个可迭代对象转换为列表。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]\n",
      "['I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 's', 'g', 'o', 'G', 'r', 'o', 'u', 'p']\n",
      "[1, 1, 2, 3, 5, 8]\n"
     ]
    }
   ],
   "source": [
    "a = list()\n",
    "print(a)  # []\n",
    "\n",
    "b = 'I Love LsgoGroup'\n",
    "b = list(b)\n",
    "print(b)  \n",
    "# ['I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 's', 'g', 'o', 'G', 'r', 'o', 'u', 'p']\n",
    "\n",
    "c = (1, 1, 2, 3, 5, 8)\n",
    "c = list(c)\n",
    "print(c)  # [1, 1, 2, 3, 5, 8]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `tuple(sub)` 把一个可迭代对象转换为元组。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "()\n",
      "('I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 's', 'g', 'o', 'G', 'r', 'o', 'u', 'p')\n",
      "(1, 1, 2, 3, 5, 8)\n"
     ]
    }
   ],
   "source": [
    "a = tuple()\n",
    "print(a)  # ()\n",
    "\n",
    "b = 'I Love LsgoGroup'\n",
    "b = tuple(b)\n",
    "print(b)  \n",
    "# ('I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 's', 'g', 'o', 'G', 'r', 'o', 'u', 'p')\n",
    "\n",
    "c = [1, 1, 2, 3, 5, 8]\n",
    "c = tuple(c)\n",
    "print(c)  # (1, 1, 2, 3, 5, 8)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `str(obj)` 把obj对象转换为字符串\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n"
     ]
    }
   ],
   "source": [
    "a = 123\n",
    "a = str(a)\n",
    "print(a)  # 123"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `len(s)` 返回对象（字符、列表、元组等）长度或元素个数。\n",
    "    - `s` -- 对象。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "16\n",
      "16\n"
     ]
    }
   ],
   "source": [
    "a = list()\n",
    "print(len(a))  # 0\n",
    "\n",
    "b = ('I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 's', 'g', 'o', 'G', 'r', 'o', 'u', 'p')\n",
    "print(len(b))  # 16\n",
    "\n",
    "c = 'I Love LsgoGroup'\n",
    "print(len(c))  # 16"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `max(sub)`返回序列或者参数集合中的最大值\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "99\n",
      "v\n"
     ]
    }
   ],
   "source": [
    "print(max(1, 2, 3, 4, 5))  # 5\n",
    "print(max([-8, 99, 3, 7, 83]))  # 99\n",
    "print(max('IloveLsgoGroup'))  # v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `min(sub)`返回序列或参数集合中的最小值\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "-8\n",
      "G\n"
     ]
    }
   ],
   "source": [
    "print(min(1, 2, 3, 4, 5))  # 1\n",
    "print(min([-8, 99, 3, 7, 83]))  # -8\n",
    "print(min('IloveLsgoGroup'))  # G"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `sum(iterable[, start=0])` 返回序列`iterable`与可选参数`start`的总和。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "25\n",
      "35\n",
      "25\n",
      "45\n"
     ]
    }
   ],
   "source": [
    "print(sum([1, 3, 5, 7, 9]))  # 25\n",
    "print(sum([1, 3, 5, 7, 9], 10))  # 35\n",
    "print(sum((1, 3, 5, 7, 9)))  # 25\n",
    "print(sum((1, 3, 5, 7, 9), 20))  # 45"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `sorted(iterable, key=None, reverse=False) ` 对所有可迭代的对象进行排序操作。\n",
    "    - `iterable` -- 可迭代对象。\n",
    "    - `key` -- 主要是用来进行比较的元素，只有一个参数，具体的函数的参数就是取自于可迭代对象中，指定可迭代对象中的一个元素来进行排序。\n",
    "    - `reverse` -- 排序规则，`reverse = True` 降序 ， `reverse = False` 升序（默认）。\n",
    "    - 返回重新排序的列表。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-8, 3, 7, 83, 99]\n",
      "[99, 83, 7, 3, -8]\n",
      "[{'age': 10, 'name': 'c'}, {'age': 20, 'name': 'a'}, {'age': 25, 'name': 'b'}]\n"
     ]
    }
   ],
   "source": [
    "x = [-8, 99, 3, 7, 83]\n",
    "print(sorted(x))  # [-8, 3, 7, 83, 99]\n",
    "print(sorted(x, reverse=True))  # [99, 83, 7, 3, -8]\n",
    "\n",
    "t = ({\"age\": 20, \"name\": \"a\"}, {\"age\": 25, \"name\": \"b\"}, {\"age\": 10, \"name\": \"c\"})\n",
    "x = sorted(t, key=lambda a: a[\"age\"])\n",
    "print(x)\n",
    "# [{'age': 10, 'name': 'c'}, {'age': 20, 'name': 'a'}, {'age': 25, 'name': 'b'}]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `reversed(seq)` 函数返回一个反转的迭代器。\n",
    "    - `seq` -- 要转换的序列，可以是 tuple, string, list 或 range。\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'reversed'>\n",
      "<reversed object at 0x7fd0040b3940>\n",
      "['p', 'u', 'o', 'r', 'g', 'o', 'g', 's', 'l']\n",
      "['p', 'u', 'o', 'r', 'g', 'o', 'g', 's', 'l']\n",
      "[8, 7, 6, 5]\n",
      "[83, 7, 3, 99, -8]\n"
     ]
    }
   ],
   "source": [
    "s = 'lsgogroup'\n",
    "x = reversed(s)\n",
    "print(type(x))  # <class 'reversed'>\n",
    "print(x)  # <reversed object at 0x000002507E8EC2C8>\n",
    "print(list(x))\n",
    "# ['p', 'u', 'o', 'r', 'g', 'o', 'g', 's', 'l']\n",
    "\n",
    "t = ('l', 's', 'g', 'o', 'g', 'r', 'o', 'u', 'p')\n",
    "print(list(reversed(t)))\n",
    "# ['p', 'u', 'o', 'r', 'g', 'o', 'g', 's', 'l']\n",
    "\n",
    "r = range(5, 9)\n",
    "print(list(reversed(r)))\n",
    "# [8, 7, 6, 5]\n",
    "\n",
    "x = [-8, 99, 3, 7, 83]\n",
    "print(list(reversed(x)))\n",
    "# [83, 7, 3, 99, -8]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "- `enumerate(sequence, [start=0])`\n",
    "\n",
    "\n",
    "\n",
    "【例子】用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列，同时列出数据和数据下标，一般用在 for 循环当中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]\n",
      "[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]\n",
      "0,Spring\n",
      "1,Summer\n",
      "2,Fall\n",
      "3,Winter\n"
     ]
    }
   ],
   "source": [
    "seasons = ['Spring', 'Summer', 'Fall', 'Winter']\n",
    "a = list(enumerate(seasons))\n",
    "print(a)  \n",
    "# [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]\n",
    "\n",
    "b = list(enumerate(seasons, 1))\n",
    "print(b)  \n",
    "# [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]\n",
    "\n",
    "for i, element in a:\n",
    "    print('{0},{1}'.format(i, element))\n",
    "# 0,Spring\n",
    "# 1,Summer\n",
    "# 2,Fall\n",
    "# 3,Winter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "- `zip(iter1 [,iter2 [...]])`\n",
    "    - 用于将可迭代的对象作为参数，将对象中对应的元素打包成一个个元组，然后返回由这些元组组成的对象，这样做的好处是节约了不少的内存。\n",
    "    - 我们可以使用 `list()` 转换来输出列表。\n",
    "    - 如果各个迭代器的元素个数不一致，则返回列表长度与最短的对象相同，利用 `*` 号操作符，可以将元组解压为列表。例: `zip(*zipped)`\n",
    "\n",
    "【例子】"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<zip object at 0x7fd00403aec8>\n",
      "[(1, 4), (2, 5), (3, 6)]\n",
      "[(1, 4), (2, 5), (3, 6)]\n",
      "[1, 2, 3]\n",
      "[4, 5, 6]\n"
     ]
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "b = [4, 5, 6]\n",
    "c = [4, 5, 6, 7, 8]\n",
    "\n",
    "zipped = zip(a, b)\n",
    "print(zipped)  # <zip object at 0x000000C5D89EDD88>\n",
    "print(list(zipped))  # [(1, 4), (2, 5), (3, 6)]\n",
    "zipped = zip(a, c)\n",
    "print(list(zipped))  # [(1, 4), (2, 5), (3, 6)]\n",
    "\n",
    "a1, a2 = zip(*zip(a, b))\n",
    "print(list(a1))  # [1, 2, 3]\n",
    "print(list(a2))  # [4, 5, 6]"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": true,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "355.556px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
